home *** CD-ROM | disk | FTP | other *** search
- static char rcsid[] = "$Id: keytable.c,v 1.1 1992/09/14 13:02:14 mike Exp $";
-
- /* $Log: keytable.c,v $
- * Revision 1.1 1992/09/14 13:02:14 mike
- * Initial revision
- *
- */
-
- /* keytable.c : deal with KeyTables.
- * A KeyTable is a dTable of Keys. Like so:
- * typedef struct { KeyCode <keyname>; <other key stuff>; } Key;
- * typedef declare_dTable_of(Key) KeyTable;
- * (you can use your own names - it don't matter to this code).
- * It is real important that a KeyCode is the first element of a Key.
- * C Durland
- */
-
- /* Copyright 1990, 1991 Craig Durland
- * Distributed under the terms of the GNU General Public License.
- * Distributed "as is", without warranties of any kind, but comments,
- * suggestions and bug reports are welcome.
- */
-
- #include <dtable.h>
- #include <const.h>
- #include "ed.h"
-
- char *Efind_key(kt,keycode) dTable *kt; register KeyCode keycode;
- {
- register char *key;
- register int n, keysize;
-
- key = kt->table; n = sizeof_dTable(kt); keysize = kt->blob_size;
- for (; n--; key += keysize) if (*(KeyCode *)key==keycode) return key;
- return NULL;
- }
-
- /* Allocate a key in the keytable. Reuse key if keycode already in the
- * table.
- * Returns:
- * ptr to key that needs to be filled in.
- * NULL: no memory
- */
- char *Ekalloc(kt,kc) dTable *kt; KeyCode kc;
- {
- register char *key;
-
- if (!(key = Efind_key(kt,kc)))
- { /* key don't exist, make room in table */
- if (!xpand_dTable(kt,1,10,10)) return NULL;
- key = &kt->table[(sizeof_dTable(kt) -1)*kt->blob_size];
- }
- return key;
- }
-
- /* Pack a keytable. remove_key() is called with a pointer to a key. If
- * TRUE is returned, the key is taken out of the table.
- * Assume: Not many keys will be removed from key table.
- * Note:
- * This routine could be made a lot faster with this alg:
- * walk till dead key
- * 1: ptr = dead
- * walk while dead key
- * qtr = dead +1
- * walk till dead key
- * blkmov(ptr,qtr,dead-qtr) ; an overlapping block move
- * goto 1
- */
- void Epack_keytable(kt,remove_key) dTable *kt; int (*remove_key)();
- {
- register char *ptr, *key;
- register int keysize, k,n;
-
- n = sizeof_dTable(kt); key = kt->table; keysize = kt->blob_size;
- for (k = 0; n--; key += keysize, k++)
- if ((*remove_key)(key))
- {
- for (ptr = key, key += keysize; n--; key += keysize)
- if (!(*remove_key)(key))
- { memcpy(ptr,key,keysize); ptr += keysize; k++; }
- sizeof_dTable(kt) = k;
- break;
- }
- }
-
- static KeyCode zap_keycode; /* a bit of ugliness here */
- static int zap_key(key) char *key;
- { return *(KeyCode *)key == zap_keycode; }
-
- void Eunbind_key(kt,keycode) dTable *kt; KeyCode keycode;
- {
- zap_keycode = keycode;
- Epack_keytable(kt,zap_key);
- }
-